import uuid
from datetime import timedelta, datetime
from typing import Dict, Any, Optional
from jose import jwt
from application import settings


class JWTTool(object):
    """JWT工具类"""
    JWTError = jwt.JWTError  # 导入JWTError
    ExpiredSignatureError = jwt.ExpiredSignatureError  # 导入ExpiredSignatureError

    def create_token(self, data: Dict[str, Any], expires_delta: Optional[timedelta] = None):
        """生成JWT"""
        """
        :param data: JWT载荷
        :param expires_delta: 过期时间 单位 秒
        :return: JWT
        """
        now_time = datetime.utcnow()
        if expires_delta:
            expire = now_time + timedelta(seconds=expires_delta.total_seconds())
        else:
            expire = now_time + timedelta(seconds=(settings.JWT['access_token_expire_time']))  # 默认过期时间为24小时
        # 载荷中添加过期时间、签发时间、生效时间、唯一标记
        payload = {
            "exp": expire,  # 过期时间
            "iat": now_time,  # 签发时间
            "nbf": now_time,  # 生效时间
            "jti": str(uuid.uuid4()),  # 唯一标记
        }
        payload.update(data)  # 载荷更新

        # 生成JWT
        return jwt.encode(payload, settings.JWT['secret_key'], algorithm=settings.JWT['algorithm'])

    def verify_token(token: str) -> Dict[str, Any]:

            """验证JWT"""

            try:
                payload = jwt.decode(token, settings.JWT['secret_key'], algorithms=[settings.JWT['algorithm']])
            except jwt.ExpiredSignatureError:
                raise self.ExpiredSignatureError("Token过期")
            except jwt.JWTError:
                raise self.JWTError("Token验证失败")
            return payload


# 实例化JWT工具类
JwtToken = JWTTool()
